import { List, Image, Typography, Input, Select, Button, Tag, message, Popconfirm, Space } from "antd"
import type { BookResponse } from "../../../../api/welcome/type"
import VirtualList from 'rc-virtual-list';
import { useEffect, useRef, useState } from "react";
import { errorImage } from "../../../../assets/error";
import { deleteBook, downloadBook, queryBook, remove } from "../../../../api/welcome/book";
import { DeleteOutlined, DownloadOutlined, SearchOutlined } from "@ant-design/icons";
import { useDebounceFn } from "ahooks";
import { useLoaderData } from "react-router";
import BookForm, { type BookFormRef } from "./BookForm";

const { Text, Paragraph } = Typography

const TAG_COLORS = [
  'magenta',
  'red',
  'volcano',
  'orange',
  'gold',
  'lime',
  'green',
  'cyan',
  'blue',
  'geekblue',
  'purple'
];


const BookList: React.FC<{
  bookList: BookResponse[]
  appendBook: (bookList: BookResponse[], isAppend?: boolean) => void
}> = ({ bookList, appendBook }) => {
  const user = useLoaderData()
  const [whichExpanded, setWhichExpanded] = useState<string>()
  const [page, setPage] = useState<number>(1)
  const [keyword, setKeyword] = useState<string>()
  const [sortType, setSortType] = useState<number>(0)
  const [total, setTotal] = useState<number>(-1)
  const bookFormRef = useRef<BookFormRef>(null);
  const [downloadLoading, setDownloadLoading] = useState<boolean>(false)
  const [deleteLoading, setDeleteLoading] = useState<boolean>(false)
  const getBookList = useDebounceFn(
    async (isAppend: boolean = true) => {
      const res = await queryBook({
        page: isAppend ? page : 1,
        keyword: keyword,
        sortType: sortType
      })
      if (res.code == 200) {
        appendBook(res.data.data, isAppend)
        setTotal(res.data.total)
        if (isAppend) {
          setPage(old => old + 1)
        } else {
          setPage(2)
        }
      }
    },
    { wait: 100 });

  useEffect(() => {
    getBookList.run(false)
  }, [keyword, sortType]);

  const onScroll = (e: React.UIEvent<HTMLElement, UIEvent>) => {
    // Refer to: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#problems_and_solutions
    if (
      Math.abs(e.currentTarget.scrollHeight - e.currentTarget.scrollTop - 480) <= 1
    ) {

      if (bookList.length < total) {
        getBookList.run()
      }
    }
  };

  const onExpand = (id: string | undefined) => {
    setWhichExpanded((old) => id == old ? undefined : id)
  }

  const handleDownloadBook = async (id?: string, objName?: string, filename?: string) => {
    if (id && objName && filename) {
      setDownloadLoading(true)
      try {
        const res = await downloadBook(id, objName)
        // 创建 Blob 和下载链接
        const blob = new Blob([res.data]);
        const link = document.createElement('a');
        link.href = URL.createObjectURL(blob);
        link.download = filename;
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);

        // 释放内存
        URL.revokeObjectURL(link.href);
      } catch (error) {
        message.error("下载文件失败")
      }
      setDownloadLoading(false)
    }
  }

  const handleDeleteBook = async (id?: string) => {
    if (id) {
      setDeleteLoading(true)
      const res = await deleteBook(id)
      if (res.code == 200) {
        const res2 = await remove(id)
        if (res2.code == 200) {
          message.success("删除成功")
          getBookList.run(false)
        }
      }
      setDeleteLoading(false)
    }
  }

  return <>
    <List
      header={
        <>
          <div className="flex gap-2 w-full mb-1">
            <Input
              allowClear
              suffix={<SearchOutlined />}
              placeholder="输入关键词"
              value={keyword}
              onChange={(e: any) => setKeyword(e.target.value)}
              className="!w-2/3" />
            <Select value={sortType} onChange={(value: number) => setSortType(value)} options={[
              { label: "最新上架", value: 0 },
              { label: "下载次数", value: 1 },
              { label: "阅读次数", value: 2 },
              { label: "出版时间", value: 3 }
            ]} className="!w-1/3" />
          </div>
          {user?.role <= 1 && <Button onClick={() => bookFormRef.current?.openModal()} block type="primary" >上传</Button>}
        </>
      }
      footer={<div className="flex justify-end">
        <strong>当前 {bookList.length} 本,共计 {total} 本</strong>
      </div>}

    >
      <VirtualList
        data={bookList}
        height={480}
        itemKey="id"
        onScroll={onScroll}
      >
        {(item: BookResponse) => (
          <List.Item>
            <List.Item.Meta
              avatar={<Image src={item.coverUrl} width={100} fallback={errorImage} />}
              title={
                <>
                  <Text strong ellipsis={{ tooltip: item.title }}>
                    {item.title}
                  </Text>
                  <br />
                  <Text strong>
                    {item.author}
                  </Text>

                </>}
              description={
                <>
                  <Paragraph
                    type="secondary"
                    ellipsis={{
                      rows: 5,
                      expandable: 'collapsible',
                      expanded: item?.id == whichExpanded,
                      onExpand: () => onExpand(item?.id)
                    }}>
                    {`摘要:${item?.summary}`}
                  </Paragraph>
                  <Space direction='vertical'>
                    <div>
                      <p><strong>分类</strong></p>
                      <Space size={[8, 8]} wrap>
                        {item?.category?.split(',').map((tag: string, index: number) => <Tag key={index} color={TAG_COLORS[index % TAG_COLORS.length]} >{tag}</Tag>)}
                      </Space>
                    </div>
                    <div>
                      <p><strong>标签</strong></p>
                      <Space size={[8, 8]} wrap>
                        {item?.tags?.split(',').map((tag: string, index: number) => <Tag key={index} color={TAG_COLORS[index % TAG_COLORS.length]} >{tag}</Tag>)}
                      </Space>
                    </div>
                  </Space>
                  <div className="flex justify-end mt-1" >
                    <Space>
                      <Popconfirm
                        title="删除书籍"
                        description="确定删除该书籍?"
                        okText="确定"
                        cancelText="取消"
                        onConfirm={() => handleDeleteBook(item.id)}
                      >
                        <Button loading={deleteLoading} danger icon={<DeleteOutlined />} />
                      </Popconfirm>
                      <Button loading={downloadLoading} type="primary" icon={<DownloadOutlined />} onClick={() => handleDownloadBook(item?.id, item.bookFile?.objName, item.bookFile?.filename)} />
                    </Space>
                  </div>
                </>
              }
            />
          </List.Item>
        )}
      </VirtualList>
    </List>
    <BookForm update={() => getBookList.run(false)} ref={bookFormRef} />
  </>

}

export default BookList
